perm filename PUP0A.RSX[11,HE] blob
sn#656314 filedate 1982-04-29 generic text, type T, neo UTF8
; Copyright Xerox Corporation 1979
.TITLE PUP0A
.DSABL GBL
.MCALL QIO$
.MCALL QIO$S
.MCALL DIR$
.MCALL ALUN$S
.MCALL ASTX$S
.MCALL DSAR$S
.MCALL ENAR$S
.MCALL IOERR$
.GLOBL IO.KIL
.GLOBL IO.WLB
.GLOBL IO.RLB
IOERR$
.CSECT GLOBAL
G=.
.=G+144.+144.
.WORD FILTER
.WORD SEIN
.WORD SEOUT
.WORD INEIO
.CSECT
.LIST MEB
SETTIM=G+122.+122.
NDBQ=G+190.+190.
PBIFQ=G+191.+191.
;
;QUEUE STRUCTURE
;
HEAD=0
TAIL=2
;
;PBI DATA STRUCTURE
;
LINK=0.
TQUEUE=2.
SOCKET=4.
NDB=6.
STATUS=8.
TIMER=10.
PLNGTH=12.
ENCAP1=14.
ENCAP2=16.
LENGTH=18.
;
;ETHER NDB DATA STRUCTURE
;
ELINK=0.
LNET=2.
LHOST=4.
DEVNUM=6.
NGPBI=8.
PFQ=10.
PLINK=14.
PPRED=16.
PQUEUE=18.
ENCPUP=20.
XMIT=22.
STATS=24.
ICCNT=26.
ICADDR=28.
ICSTAT=30.
IPBI=32.
OCCNT=34.
OCADDR=36.
OCSTAT=38.
OCDLAY=40.
LOAD=42.
XMTTIM=44.
OPBI=46.
OQ=48.
;
;PACKET FILTER DATA STRUCTURE
;
PFLINK=0
PFPRED=2
PFQUE=4
;
;MISCELLANEOUS CONSTANTS
;
PUP=1000 ;PUP IDENTIFIER
PUPSIZ=560.
;
;MACRO CALLS
;
HOST: QIO$ 3000,6,,,IOSB
IOSB: .BLKW 2
;
OUTPUT:
.BYTE 1,12.
.WORD IO.WLB
.WORD 5
.BYTE 0,0
.WORD IOSB1
.WORD OUTAST
OUTARG:
.BLKW 6
IOSB1: .BLKW 2
;
INPUT:
.BYTE 1,12.
.WORD IO.RLB
.WORD 6
.BYTE 0,0
.WORD IOSB2
.WORD INAST
INARG:
.BLKW 6
IOSB2: .BLKW 2
.PAGE
;
;SUBROUTINE InitEtherIO() = host
;
INEIO::
ALUN$S #5,EN,#0,ERROR ;ASSIGN LUN FOR OUTPUT
ALUN$S #6,EN,#1,ERROR ;ASSIGN LUN FOR INPUT
;
;CANCEL I/O
;
QIO$S #IO.KIL,#6
;
;GET AND RETURN HOST ADDRESS
;
DIR$ #HOST,ERROR
MOV IOSB+2,R1 ;HOST ADDRESS
;
ADD #2,0(SP)
RTS PC ;RETURN
EN: .ASCII /EN/ ;DEVICE NAME IS 'EN'
.PAGE
;
;SUBROUTINE OUTAST
;
;ENTERED BY INTERRUPT AFTER TRANSMISSION
;
OUTAST::
TST (SP)+ ;REMOVE ADDR OF IOSB
MOV R1,-(SP) ;PUSH R1
MOV R2,-(SP) ;PUSH R2
MOV R3,-(SP) ;PUSH R3
;
MOV NDBQ,R3 ;
ASL R3 ;
MOV @R3,R3 ;
ASL R3 ;R3 = NDB ADDRESS
MOV OPBI(R3),R2 ;
ASL R2 ;R2 = PBI ADDRESS
CMP IOSB1,#IS.SUC ;GOOD COMPLETION?
BEQ OUTAS2 ;YES, BRANCH
TST LOAD(R3) ;NO, LOAD OVERFLOW?
BPL OUTAS3 ;NO, BRANCH
OUTAS2:
MOV TQUEUE(R2),R1 ;R1 = TQUEUE
CLC
ROR R2
JSR PC,NQ ;ENQUEUE PBI ON TQUEUE
.WORD 0 ;
;
CLR OPBI(R3) ;NDB.OPBI = 0
CLR LOAD(R3) ;NDB.LOAD = 0
;
OUTAS3:
MOV R3,R1 ;R1 = NDB ADDRESS
CLC
ROR R1
JSR PC,$SEOUT ;START ETHER OUTPUT
.WORD 0 ;
;
MOV (SP)+,R3 ;POP R3
MOV (SP)+,R2 ;POP R2
MOV (SP)+,R1 ;POP R1
ASTX$S ;RETURN FROM AST
.PAGE
;
;SUBROUTINE INAST
;
;ENTERED BY INTERRUPT AFTER RECEIPT OF PACKET
;
INAST::
TST (SP)+ ;REMOVE ADDR OF IOSB
MOV R4,-(SP) ;PUSH R4
MOV R3,-(SP) ;PUSH R3
MOV R2,-(SP) ;PUSH R2
MOV R1,-(SP) ;PUSH R1
;
MOV NDBQ,R3 ;
ASL R3 ;
MOV @R3,R3 ;
ASL R3 ;R3 = NDB ADDRESS
MOV IPBI(R3),R2 ;
ASL R2 ;R2 = PBI ADDRESS
ASR IOSB2+2 ;CONVERT BYTE CNT TO WORD CNT
MOV IOSB2+2,ICCNT(R3) ;INPUT WORD COUNT
MOV IOSB2+2,PLNGTH(R2) ;PBI.PACKET LENGTH
;
MOV R3,R1 ;
CLC
ROR R1
MOV R1,NDB(R2) ;PBI.NDB
;
CMP IOSB2,#IS.SUC ;GOOD COMPLETION?
BNE INAST3 ;NO, BRANCH
;
MOV PFQ(R3),R4 ;
ASL R4 ;R4 = ADDRESS OF PF
INAST1:
BEQ INAST3 ;BRANCH IF NO MORE PF'S
MOV R2,R1 ;R1 = PBI ADDRESS
CLC
ROR R1
JSR PC,@PFPRED(R4) ;EXECUTE ETHER PUP FILTER
.WORD 0
TST R1 ;GOOD PUP?
BNE INAST2 ;YES, BRANCH
MOV PFLINK(R4),R4 ;
ASL R4 ;R4 = ADDRESS OF NEXT PF
BR INAST1 ;TRY AGAIN
;
INAST2:
MOV PFQUE(R4),R1 ;QUEUE PBI ON PBIIQ
CLC
ROR R2
JSR PC,NQ ;
.WORD 0
;
CLR IPBI(R3) ;NDB.IPBI = 0
;
INAST3:
CMP IOSB2,#IE.ABO
BEQ INAST4 ;CANCEL I/O PERFORMED
MOV R3,R1 ;R1 = NDB ADDRESS
CLC
ROR R1
JSR PC,$SEIN ;START ETHER INPUT
.WORD 0
;
INAST4:
MOV (SP)+,R1 ;POP R1
MOV (SP)+,R2 ;POP R2
MOV (SP)+,R3 ;POP R3
MOV (SP)+,R4 ;POP R4
ASTX$S ;RETURN FROM AST
.PAGE
;
;SUBROUTINE EtherPupFilter(pbi) = true/false
;
FILTER::
MOV R3,-(SP) ;PUSH R3
MOV R2,-(SP) ;PUSH R2
;
ASL R1 ;
MOV R1,R2 ;R2 = PBI ADDRESS
CLR R1 ;RESULT = FALSE
CMP ENCAP2(R2),#PUP ;TYPE = 'PUP'?
BNE FLTER5 ;NO, BRANCH
MOV LENGTH(R2),R3 ;PUP.LENGTH
ADD #5,R3 ; + 5
ASR R3 ; /2
CMP R3,PLNGTH(R2) ; = PACKET LENGTH?
BNE FLTER5 ;NO, BRANCH
DEC R1 ;RESULT = TRUE
FLTER5:
MOV (SP)+,R2 ;POP R2
MOV (SP)+,R3 ;POP R3
ADD #2,0(SP) ;
RTS PC ;RETURN
.PAGE
;
;SUBROUTINE StartEtherInput(ndb)
;
SEIN::
MOV R0,-(SP) ;PUSH R0
MOV R2,-(SP) ;PUSH R2
MOV R3,-(SP) ;PUSH R3
DSAR$S ;DISABLE AST
JSR PC,$SEIN
.WORD 0
ENAR$S ;ENABLE AST
MOV (SP)+,R3 ;POP R3
MOV (SP)+,R2 ;POP R2
MOV (SP)+,R0 ;POP R0
ADD #2,0(SP) ;
RTS PC ;RETURN
;
$SEIN:
MOV R1,R2 ;
ASL R2 ;R2 = NDB ADDRESS
TST IPBI(R2) ;IS NDB.IPBI = 0?
BNE SEIN1 ;NO, BRANCH
;
MOV PBIFQ,R1 ;
JSR PC,DQ ;DEQUEUE PBI FROM PBIFREEQ
.WORD 0 ;
MOV R1,IPBI(R2) ;SET NEW NDB.IPBI
;
SEIN1:
MOV IPBI(R2),R3 ;
ASL R3 ;R3 = NDB.IPBI
BEQ SEIN2 ;PBIFREEQ EMPTY, BRANCH
;
ADD #ENCAP1,R3 ;R3 = PACKET ADDRESS
MOV R3,ICADDR(R2) ;
;
MOV #PUPSIZ,INARG+2 ;SET MAX BYTE COUNT
MOV ICADDR(R2),INARG ;SET BUFFER ADDRESS
;
DIR$ #INPUT,ERROR ;QIO
SEIN2:
ADD #2,0(SP) ;
RTS PC ;RETURN
.PAGE
;
;SUBROUTINE StartEtherOutput(ndb)
;
SEOUT::
MOV R0,-(SP) ;PUSH R0
MOV R2,-(SP) ;PUSH R2
MOV R3,-(SP) ;PUSH R3
DSAR$S ;DISABLE AST
JSR PC,$SEOUT
.WORD 0
ENAR$S ;ENABLE AST
MOV (SP)+,R3 ;POP R3
MOV (SP)+,R2 ;POP R2
MOV (SP)+,R0 ;POP R0
ADD #2,0(SP) ;
RTS PC ;RETURN
;
$SEOUT:
MOV R1,R2 ;
ASL R2 ;R2 = NDB ADDRESS
TST OPBI(R2) ;IS NDB.OPBI = 0?
BNE SEOUT1 ;NO, BRANCH
;
MOV R2,R1
ADD #OQ,R1
CLC
ROR R1
JSR PC,DQ ;DEQUEUE PBI FROM NDB.OQ
.WORD 0 ;
MOV R1,OPBI(R2) ;SET NEW NDB.OPBI
;
SEOUT1:
MOV OPBI(R2),R3 ;
ASL R3 ;R3 = NDB.OPBI
BEQ SEOUT2 ;NDB.OQ EMPTY, BRANCH
;
; SET TRANSMIT TIMEOUT FOR 1 SECOND
;
MOV R2,R1
ADD #XMTTIM,R1
CLC
ROR R1
MOV R2,-(SP)
MOV #10.,R2
JSR PC,@SETTIM ;SET TIMER
.WORD 0 ;
MOV (SP)+,R2
;
MOV PLNGTH(R3),OCCNT(R2)
MOV OCCNT(R2),OUTARG+2
ASL OUTARG+2 ;SET OUTPUT BYTE COUNT
ADD #ENCAP1,R3 ;
MOV R3,OCADDR(R2) ;
MOV R3,OUTARG ;SET BUFFER ADDRESS
;
MOV OCDLAY(R2),R3 ;CALCULATE RANDOM NUMBER
ASH #9.,R3 ;
ADD OCDLAY(R2),R3 ;
ASH #2.,R3 ;
ADD OCDLAY(R2),R3 ;
ADD #13849.,R3 ;
MOV R3,OCDLAY(R2) ;
;
MOV LOAD(R2),R1 ;CALCULATE OUTPUT START DELAY
NEG R1 ;
ASH #-8.,R3 ;
NEG R3 ;
BIS R1,R3 ;
NEG R3 ;R3 = RANDOM/256 .AND. NDB.LOAD
MOVB R3,OUTARG+4 ;SET OUTPUT START DELAY
;
ASL LOAD(R2) ;LOAD = 2*LOAD+1
ADD #1,LOAD(R2) ;
;
DIR$ #OUTPUT,ERROR ;QIO
SEOUT2:
ADD #2,0(SP) ;
RTS PC ;RETURN
;
ERROR:
HALT ;I/O ERROR
.PAGE
;
;SUBROUTINE Enqueue(queue,item)
;
NQ::
ASL R1
MOV R3,-(SP) ;PUSH R3
MOV R4,-(SP) ;PUSH R4
MOV R2,R3
ASL R3
CLR LINK(R3) ;LINK OF NEW TAIL = 0
TST HEAD(R1) ;IS QUEUE EMPTY?
BNE QUSED ;NO, BRANCH
MOV R2,HEAD(R1) ;YES, UPDATE HEAD POINTER
BR NOTAIL ;
QUSED:
MOV TAIL(R1),R4 ;UPDATE LINK OF PREVIOUS TAIL
ASL R4 ;
MOV R2,@R4 ;
NOTAIL:
MOV R2,TAIL(R1) ;UPDATE TAIL POINTER
MOV (SP)+,R4 ;POP R4
MOV (SP)+,R3 ;POP R3
ADD #2,0(SP) ;
RTS PC ;RETURN
;
;SUBROUTINE Dequeue(queue) = item
;
DQ:
ASL R1
MOV R2,-(SP) ;PUSH R2
MOV R3,-(SP) ;PUSH R3
MOV R4,-(SP) ;PUSH R4
MOV HEAD(R1),R3 ;RETURN ITEM ADDR TO CALLER
BEQ NOQUE ;
MOV HEAD(R1),R4
ASL R4
MOV @R4,HEAD(R1) ;HEAD = NEXT ITEM
TST HEAD(R1) ;TEST NEXT ITEM
BNE TAILOK ;BRANCH IF QUEUE NOT EMPTY
CLR TAIL(R1) ;QUEUE EMPTY, TAIL = 0
NOQUE: ;
TAILOK: ;
MOV R3,R1 ;R1 = ITEM ADDRESS
MOV (SP)+,R4 ;POP R4
MOV (SP)+,R3 ;POP R3
MOV (SP)+,R2 ;POP R2
ADD #2,0(SP) ;
RTS PC ;RETURN
.END